-- Copyright James McGill, 2010
-- Author: James McGill (jmcgill@plexer.net)

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library unisim;
use unisim.vComponents.all;

-- Generate 8, 4, 2 and 1 MHz clocks from a 50 MHz input source.
-- This implements a subset of the functionality encapsulated
-- in the BBC Model B Video ULA.
entity clock_generator is
    Port ( reset : in std_logic;
	        clock_50mhz : in  std_logic;
			  clock_48mhz : inout std_logic;
			  clock_24mhz : out std_logic;
           clock_8mhz : inout  std_logic;
			  clock_4mhz : inout  std_logic;
			  clock_2mhz : inout  std_logic;
           clock_1mhz : inout  std_logic;
			  locked : out std_logic);
end clock_generator;

architecture Behavioral of clock_generator is

	-- Automatically generated declaration for Xilinx DCM IP.
	-- NOTE(jmcgill): This is now actually 48 MHz.
	COMPONENT dcm_32mhz
	PORT(
		CLKIN_IN : IN std_logic;
		RST_IN : IN std_logic;          
		CLKFX_OUT : OUT std_logic;
		CLK0_OUT : OUT std_logic;
		LOCKED_OUT : OUT std_logic
		);
	END COMPONENT;

	COMPONENT vga_clock
	PORT(
		CLKIN_IN : IN std_logic;
		RST_IN : IN std_logic;          
		CLKFX_OUT : OUT std_logic;
		CLK0_OUT : OUT std_logic;
		LOCKED_OUT : OUT std_logic
		);
	END COMPONENT;

	component clock_divider is
    port ( clock : in  std_logic;
           divide_by_2x : in  std_logic_vector (7 downto 0);
           clock_out : inout  std_logic);
	end component;

begin
  
   -- Automatically generated instantiation for Xilinx DCM IP.
	-- TODO(jmcgill): 32mhz -> 8mhz
	Inst_dcm_32mhz: dcm_32mhz PORT MAP(
		CLKIN_IN => clock_50mhz,
		RST_IN => reset,
		CLKFX_OUT => clock_8mhz,
		CLK0_OUT => clock_24mhz,  -- 50 Mhz buffer clock for hacked VGA.
		LOCKED_OUT =>  locked
	);

--	Inst_vga_clock: vga_clock PORT MAP(
--		CLKIN_IN => clock_50mhz,
--		RST_IN => reset,
--		CLKFX_OUT => clock_24mhz,
--		CLK0_OUT => open,
--		LOCKED_OUT => open
--	);
	
	-- 8 MHz divided by 2 x 1 (0x01) = 4 MHz
	clock_4mhz_generator: clock_divider PORT MAP(
		clock => clock_8mhz,
		divide_by_2x => x"01",
		clock_out => clock_4mhz
	);
	
	-- 8 MHz divided by 2 x 2 (0x02) = 2 MHz
	clock_2mhz_generator: clock_divider PORT MAP(
		clock => clock_8mhz,
		divide_by_2x => x"02",
		clock_out => clock_2mhz
	);
	
	-- 8 MHz divided by 2 x 4 (0x04) = 1 MHz
	clock_1mhz_generator: clock_divider PORT MAP(
		clock => clock_8mhz,
		divide_by_2x => x"04",
		clock_out => clock_1mhz
	);
	
	clock_48mhz <= '1';
	
end Behavioral;

